home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
src
/
haeberli
/
libgutil
/
corprt4.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
7KB
|
321 lines
/*
* Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
/*
* corimg4 -
* This contains generic corimg4 and sproof4 stuff. This color
* Correction technique is for multi angle screening with 4 colors
*
* Paul Haeberli - 1991
*
* use corone4(r,g,b,cr,cg,cb)
* and sproof4(r,g,b,cr,cg,cb) in the simplest case.
*
* exports
*
void corrow4(rbuf,gbuf,bbuf,n)
void corone4(fr,fg,fb,cr,cg,cb)
void sproofrow4(rbuf,gbuf,bbuf,n)
void sproof4(r,g,b,sr,sg,sb)
*
*/
#include "stdio.h"
#include "image.h"
#include "math.h"
#include "texture.h"
#include "lum.h"
#include "swop.h"
/*
* correction stuff follows
*
*/
#define DESAT 1
#define CORTAB "/usr/lib/cortab.rgb"
#define CORMAG "/usr/lib/cortab.mag"
#define EPSILON (0.0001)
#define FLAGBIT (1<<14)
#define RSCALE (16383.0*RLUM)
#define GSCALE (16383.0*GLUM)
#define BSCALE (16383.0*BLUM)
float flerp();
static TEXTURE *tm;
static short *sbuf;
static int magxsize;
static int magysize;
static int simpcorone(fr,fg,fb,r,g,b)
float fr, fg, fb;
float *r, *g, *b;
{
int mapno;
float mag, mapx, mapy;
int imapx, imapy;
int tmsize, magtab;
float bscale;
vect c;
/* fprintf(stderr,"rgb is %f %f %f\n",fr,fg,fb); */
if(!tm) {
IMAGE *simage;
int y;
tm = tmopen(CORTAB);
if(!tm) {
fprintf(stderr,"corimg: can't open %s\n",CORTAB);
exit(1);
}
simage = iopen(CORMAG,"r");
if(!simage) {
fprintf(stderr,"corimg: can't open %s\n",CORMAG);
exit(1);
}
magxsize = simage->xsize;
magysize = simage->ysize;
sbuf = (short *)malloc(simage->xsize*simage->ysize*sizeof(short));
for(y=0; y<simage->ysize; y++)
getrow(simage,sbuf+(y*simage->xsize),y,0);
iclose(simage);
}
tmsize = tm->ysize;
if(fr<EPSILON && fg<EPSILON && fb<EPSILON) {
*r = 0.0;
*g = 0.0;
*b = 0.0;
return 1;
} else {
if(fr>fg) {
if(fr>fb) {
mapno = 0;
mapx = fg/fr;
mapy = fb/fr;
} else {
mapno = 2;
mapx = fr/fb;
mapy = fg/fb;
}
} else {
if(fg>fb) {
mapno = 1;
mapx = fb/fg;
mapy = fr/fg;
} else {
mapno = 2;
mapx = fr/fb;
mapy = fg/fb;
}
}
/* fprintf(stderr,"mapno is %d\n",mapno); */
imapx = (mapno*tmsize)+mapx*(tmsize-1.0)+0.5;
imapy = mapy*(tmsize-1.0)+0.5;
/* fprintf(stderr,"maploc is %d %d\n",imapx,imapy); */
mag = RSCALE*fr+GSCALE*fg+BSCALE*fb;
/* fprintf(stderr,"mag is %f\n",mag); */
magtab = sbuf[imapy*magxsize+imapx];
magtab &= ~FLAGBIT;
/* fprintf(stderr,"magtab is %d\n",magtab); */
bscale = mag/magtab;
/* fprintf(stderr,"bscale is %f\n",bscale); */
imgsample(tm,imapx,imapy,&c);
if(bscale <= 1.0) {
*r = (bscale*c.x);
*g = (bscale*c.y);
*b = (bscale*c.z);
return 1;
} else {
bscale = 1.0;
*r = (bscale*c.x);
*g = (bscale*c.y);
*b = (bscale*c.z);
return 0;
}
}
}
void corone4(fr,fg,fb,cr,cg,cb)
float fr, fg, fb;
float *cr, *cg, *cb;
{
float tr, tg, tb;
float r, g, b, lum;
float delta, p, goodp;
int i;
if(DESAT) {
if(!simpcorone(fr,fg,fb,&r,&g,&b)) {
lum = LUM(fr,fg,fb);
p = 0.5;
delta = 0.25;
goodp = -1.0;
for(i=0; i<8; i++) {
tr = flerp(fr,lum,p);
tg = flerp(fg,lum,p);
tb = flerp(fb,lum,p);
if(simpcorone(tr,tg,tb,&r,&g,&b)) {
goodp = p;
p -= delta;
} else
p += delta;
delta = delta/2.0;
}
if(goodp < 0.0)
goodp = 1.0;
tr = flerp(fr,lum,goodp);
tg = flerp(fg,lum,goodp);
tb = flerp(fb,lum,goodp);
simpcorone(tr,tg,tb,&r,&g,&b);
}
} else {
simpcorone(fr,fg,fb,&r,&g,&b);
}
*cr = r;
*cg = g;
*cb = b;
}
void corrow4(rbuf,gbuf,bbuf,n)
short *rbuf;
short *gbuf;
short *bbuf;
int n;
{
float cr, cg, cb;
short lr, lg, lb;
short ir, ig, ib;
lr = lg = lb = -1000;
while(n--) {
if((*rbuf != lr) || (*gbuf != lg) || (*bbuf != lb)) {
lr = *rbuf;
lg = *gbuf;
lb = *bbuf;
corone4(lr/255.0,lg/255.0,lb/255.0,&cr,&cg,&cb);
ir = cr*255.0+0.5;
ig = cg*255.0+0.5;
ib = cb*255.0+0.5;
}
*rbuf++ = ir;
*gbuf++ = ig;
*bbuf++ = ib;
}
}
/*
* sproofing stuff follows
*
*/
static float polycoef[3][4][3];
static setprinter()
{
int i;
for(i=0; i<3; i++) {
polycoef[CM][0][i] = ct[BLU][i]-ct[MAG][i]-ct[CYA][i]+1.0;
polycoef[CM][1][i] = ct[CYA][i]-1.0;
polycoef[CM][2][i] = ct[MAG][i]-1.0;
polycoef[CM][3][i] = 1.0;
polycoef[MY][0][i] = ct[RED][i]-ct[YEL][i]-ct[MAG][i]+1.0;
polycoef[MY][1][i] = ct[MAG][i]-1.0;
polycoef[MY][2][i] = ct[YEL][i]-1.0;
polycoef[MY][3][i] = 1.0;
polycoef[YC][0][i] = ct[GRE][i]-ct[CYA][i]-ct[YEL][i]+1.0;
polycoef[YC][1][i] = ct[YEL][i]-1.0;
polycoef[YC][2][i] = ct[CYA][i]-1.0;
polycoef[YC][3][i] = 1.0;
}
}
static int firsted;
static pairtorgb(pair,c,m,k,r,g,b)
int pair;
float c, m, k;
float *r, *g, *b;
{
if(!firsted) {
setprinter();
firsted = 1;
}
k = 1.0-k;
*r = k*(c*m*polycoef[pair][0][0] +
c*polycoef[pair][1][0] +
m*polycoef[pair][2][0] + 1.0);
*g = k*(c*m*polycoef[pair][0][1] +
c*polycoef[pair][1][1] +
m*polycoef[pair][2][1] + 1.0);
*b = k*(c*m*polycoef[pair][0][2] +
c*polycoef[pair][1][2] +
m*polycoef[pair][2][2] + 1.0);
}
void sproof4(r,g,b,sr,sg,sb)
float r, g, b;
float *sr, *sg, *sb;
{
int c, m, y, k;
int ir, ig, ib;
float fc, fm, fy, fk;
ir = 255.0*r;
ig = 255.0*g;
ib = 255.0*b;
rgb_to_cmyk(ir,ig,ib,&c,&m,&y,&k,0);
fc = c/255.0;
fm = m/255.0;
fy = y/255.0;
fk = k/255.0;
if(c == 0)
pairtorgb(MY,fm,fy,fk,sr,sg,sb);
else if(m == 0)
pairtorgb(YC,fy,fc,fk,sr,sg,sb);
else
pairtorgb(CM,fc,fm,fk,sr,sg,sb);
}
void sproofrow4(rbuf,gbuf,bbuf,n)
short *rbuf;
short *gbuf;
short *bbuf;
int n;
{
float cr, cg, cb;
short lr, lg, lb;
short ir, ig, ib;
lr = lg = lb = -1000;
while(n--) {
if((*rbuf != lr) || (*gbuf != lg) || (*bbuf != lb)) {
lr = *rbuf;
lg = *gbuf;
lb = *bbuf;
sproof4(lr/255.0,lg/255.0,lb/255.0,&cr,&cg,&cb);
ir = cr*255.0+0.5;
ig = cg*255.0+0.5;
ib = cb*255.0+0.5;
}
*rbuf++ = ir;
*gbuf++ = ig;
*bbuf++ = ib;
}
}